从0开始点亮OLED屏幕(二)OLED的初始化 您所在的位置:网站首页 黑屏转白屏 数字化 从0开始点亮OLED屏幕(二)OLED的初始化

从0开始点亮OLED屏幕(二)OLED的初始化

2024-07-17 05:06| 来源: 网络整理| 查看: 265

基于篇一我已经介绍了IIC的一些基本时序,本篇文章将教会你们如何初始化程序以及点亮像素点。 

一、OLED屏幕的简单介绍: 1.OLED显存介绍:

        我所使用的OLED为128*64分辨率的,即RAM为128*64位。而RAM分为8个页面,从PAGE0到PAGE7,如图所示:5d78c213f2c146e7887fbfe6d2dcc8d6.png

 而每一页有8个像素,即八位,而刚好一个字节的数据就是八位,8*8=64就是这么来的。我想这不是巧合,可能就是为了让我们可以用一个字节的数据表示某一列的八个像素点的亮灭。从下图可知,其低位是在最上面的,高位依次往下。

f43b122609884f16b7bdc6293b6c41c6.png

而我们点亮OLED相当于将这128*64个像素点点亮的过程,和点阵屏类似。

下面来介绍如何点亮OLED:

二、OLED屏幕的驱动 1.向屏幕写数据:OLED_WR_Byte

        IIC写时序图如下:

2e3694ed71304939b5053a6afae0f116.png

首先开始IIC通信(START),然后发送器件地址(DEVICE ADDRESS) :0X78;等待应答,然后发送命令(OLED命令寄存器地址:0x40;数据寄存器地址:0x00),等待应答,发送数据,等待应答,结束信号;        

//发送一个字节 //mode:数据/命令标志 0,表示命令;1,表示数据; void OLED_WR_Byte(u8 dat,u8 mode) { I2C_Start(); Send_Byte(0x78); I2C_WaitAck(); if(mode) Send_Byte(0x40); else Send_Byte(0x00); I2C_WaitAck(); Send_Byte(dat); I2C_WaitAck(); I2C_Stop(); } 2.OLED的初始化

初始化流程图:

2a13bfa109a5457082f80a286e6242c2.png

 

//OLED的初始化 void OLED_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能A端口时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_12; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA0,1 GPIO_SetBits(GPIOA,GPIO_Pin_11|GPIO_Pin_12); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA2 GPIO_SetBits(GPIOA,GPIO_Pin_15); OLED_WR_Byte(0xAE,OLED_CMD);//关闭显示(进入睡眠模式) OLED_WR_Byte(0x02,OLED_CMD);//设置低列地址 OLED_WR_Byte(0x10,OLED_CMD);//设置高列地址 OLED_WR_Byte(0xD5,OLED_CMD);//设置显示时钟分频值/震荡频率(刷新率) OLED_WR_Byte(0x80,OLED_CMD);//设置分割比率,设置时钟为100帧/秒 OLED_WR_Byte(0xA8,OLED_CMD);//设置复用率(0-63) OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty OLED_WR_Byte(0xD3,OLED_CMD);//设置显示偏移一位映射RAM计数器(0x00~0x3F) OLED_WR_Byte(0x00,OLED_CMD);//不偏移 OLED_WR_Byte(0x40,OLED_CMD);//设置起始地址 设置映射RAM显示起始行(0x00~0x3F) OLED_WR_Byte(0xA1,OLED_CMD);//设置左右方向显示 0xa1正常 0xa0左右反置 OLED_WR_Byte(0xC8,OLED_CMD);//设置上下方向显示 0xc0上下反置 0xc8正常 OLED_WR_Byte(0xDA,OLED_CMD);//设置列引脚硬件配置 OLED_WR_Byte(0x12,OLED_CMD);//12864->0x12;128*32->0x02; OLED_WR_Byte(0x81,OLED_CMD);//设置对比度控制寄存器 OLED_WR_Byte(0xCF,OLED_CMD);//设置对比度控制为0xcf(0x00-0xff) OLED_WR_Byte(0xD9,OLED_CMD);//设置充电周期 OLED_WR_Byte(0xF1,OLED_CMD);//设置预充电为15个时钟,放电为1个时钟 OLED_WR_Byte(0xDB,OLED_CMD);//设置VCOMH反压值 OLED_WR_Byte(0x30,OLED_CMD);//设置VCOM取消选择电平 OLED_WR_Byte(0x20,OLED_CMD);//设置页面寻址模式(0x00/0x01/0x02) OLED_WR_Byte(0xA6,OLED_CMD);//设置正常显示 OLED_Clear(); OLED_WR_Byte(0x8D,OLED_CMD);//设置电荷泵 OLED_WR_Byte(0x14,OLED_CMD);//设置电荷泵开启/(0x10)禁用 OLED_WR_Byte(0xAF,OLED_CMD);//开启显示(进入工作模式) } 3.点亮一个像素点:

        在OLED的这么多指令中,我们最需要了解的是如何设置列地址与页地址。在此OLED有八页,第一页page0的指令为0XB0、Page1为0xB1、依次类推,Page7则是0xB7;而列地址的设置则需要两次,比如列地址为50,也就是0x32;我们则需要发送指令0x02将列地址第四位设置为2,再发送指令0x13将列高四位设置为3;设置好列地址与页地址就可以发送一串数据点亮某一页的某一列像素亮灭了,相当于点亮八个LED灯。

eg:将第一页的第1列全部点亮:

OLED_WR_Byte(0xB0,OLED_CMD); OLED_WR_Byte(0x00,OLED_CMD); OLED_WR_Byte(0x10,OLED_CMD); OLED_WR_Byte(0xff,OLED_DATA);

                                ​​​​​​​        ​​​​​​​        374ea826dcc34c89a8d418825423ba38.jpeg

此时就成功点亮OLED了!

但是,这样的效率是比较低的,下面我来介绍另一种方法:首先定义一个二维数组,代表OLED显存,128代表其128列,8则代表8页,u8代表一页的八位数据:

u8 OLED_GRAM[128][8];

 假如要想实现上面的效果,只需要

OLED_GRAM[0][0] = 0xff; OLED_Refresh();

就能实现和上面同样的效果啦,这里加了OLED显存更新函数,目的是将二维数组OLED_GRAM里面存放的数据显示出来。

4.更新显存函数

下面来介绍更新显存函数:i代表页数,n代表列数。i=0:写入第0页,执行for语句128次便将二维数组中存的数据都显示出来,依次类推....第一个for循环里面的代码与上述一样原理,设置页地址,i等于0时为0xb0,第0页。唯一不同的是我们没有依次设置列地址了,这是由于CH1116芯片有十分人性化的特性:设置完一个字节的8个像素后,其列地址会自动加1!故我们不需要频繁改变列地址;

void OLED_Refresh(void) { u8 i,n; for(i=0;i


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有